package com.openapi.protocol.encode;

import com.openapi.data.JT808PushData;
import exsun.jt808.data.base.JT808Category;
import exsun.jt808.data.distribute_data.DistributeEntity;
import exsun.jt808.data.distribute_data.jt808.*;
import exsun.jt808.data.upload_data.jt808.LatLng;
import exsun.jt808.data.util.parse.BCD8421Operater;
import exsun.jt808.data.util.parse.BitOperator;
import exsun.jt808.data.util.parse.DecoderUtils;
import exsun.jt808.data.util.parse.HexStrUtil;

/**
 * 808组包
 */
public class Package808 {
    /**
     * 平台通用应答
     * @param data
     * @return
     */
    public static JT808PushData generalReply_0x8001(GeneralReply data) {

        byte[] body = HexStrUtil.decodeHex(BitOperator.intToHex(data.getOrgSerialNum(), 4) + BitOperator.intToHex(data.getOrgMsgId(), 4) + BitOperator.intToHex(data.getResult(),2));
        return new JT808PushData(0x8001,body,data, JT808Category.platformReplay);
    }

    /**
     * 终端注册
     * @param data
     * @return
     */
    public static JT808PushData terminalRegisterRsp_0x8100(TerminalRegisterRsp data) {
        byte[] body = BitOperator.concatAll(
                BitOperator.integerTo2Bytes(data.getOrgSerialNum()),
                BitOperator.integerTo1Bytes(data.getResult()),
                BitOperator.stringToBytes(data.getCode()));
        return new JT808PushData(0x8100,body, data, JT808Category.platformReplay);
    }
    //人工确认报警消息
    public static JT808PushData affirmAlarm_0x8203(AffirmAlarm data)
    {
        byte[] msgBodyBytes = BitOperator.concatAll(BitOperator.integerTo2Bytes(data.getSerialNo()), BitOperator.integerTo4Bytes(data.getAlarmType()));
        return new JT808PushData(0x8203, msgBodyBytes, data);
    }
    //车辆控制
    public  JT808PushData controlVehicle_0x8500(ControlVehicle data)
    {
        byte[] msgBodyBytes = BitOperator.integerTo1Bytes(data.getCmd());
        return new JT808PushData(0x8500, msgBodyBytes, data);
    }
    //删除圆形区域
    public static JT808PushData delCircleArea_0x8601(DelCircleArea data)
    {
        byte[] msgBodyBytes = BitOperator.integerTo1Bytes(data.getAreaIds().size());
        for (Integer areaId : data.getAreaIds())
        {
            msgBodyBytes = BitOperator.concatAll(msgBodyBytes, BitOperator.integerTo4Bytes(areaId));
        }
        return new JT808PushData(0x8601, msgBodyBytes, data);
    }
    //删除多边形区域
    public static JT808PushData delPolygonArea_0x8605(DelPolygonArea data)
    {
        byte[] msgBodyBytes = BitOperator.integerTo1Bytes(data.getAreaIds().size());
        for (Integer areaId : data.getAreaIds())
        {
            msgBodyBytes = BitOperator.concatAll(msgBodyBytes, BitOperator.integerTo4Bytes(areaId));
        }
        return new JT808PushData(0x8605, msgBodyBytes, data);
    }
    //删除矩形区域
    public static  JT808PushData delRectangleArea_0x8603(DelRectanglArea data)
    {
        byte[] msgBodyBytes = BitOperator.integerTo1Bytes(data.getAreaIds().size());
        for (Integer areaId : data.getAreaIds())
        {
            msgBodyBytes = BitOperator.concatAll(msgBodyBytes, BitOperator.integerTo4Bytes(areaId));
        }
        return new JT808PushData(0x8603, msgBodyBytes, data);
    }
    //删除路线
    public static JT808PushData delRoute_0x8607(DelRoute data)
    {
        byte[] msgBodyBytes = BitOperator.integerTo1Bytes(data.getLineIds().size());
        for (Integer areaId : data.getLineIds())
        {
            msgBodyBytes = BitOperator.concatAll(msgBodyBytes, BitOperator.integerTo4Bytes(areaId));
        }
        return new JT808PushData(0x8607, msgBodyBytes, data);
    }

    public static JT808PushData dediaDataRsp_0x8800(MediaDataRsp data) {
        byte[] body = null;
        if(data.getMissItems()== null||data.getMissItems().size()==0){
            body = BitOperator.integerTo2Bytes(data.getMediaId());
        }else {
            body = BitOperator.concatAll(
                    BitOperator.integerTo2Bytes(data.getMediaId()),
                    BitOperator.integerTo1Bytes(data.getMissItems().size()));
            for (Integer item: data.getMissItems()) {
                body = BitOperator.concatAll(
                        body,
                        BitOperator.integerTo2Bytes(item));
            }
        }
        JT808PushData JT808PushData = new JT808PushData(0x8800,body, data, JT808Category.platformReplay);
        return JT808PushData;
    }
    //查询终端参数
    public static JT808PushData queryParameters_0x8104(DistributeEntity data)
    {
        byte[] msgBodyBytes = new byte[0];
        return new JT808PushData(0x8104, msgBodyBytes, data);
    }
    //位置信息查询
    public static JT808PushData QueryPositionInfo_0x8201(DistributeEntity data)
    {
        // 消息体为空
        byte[] msgBodyBytes = new byte[0];
        return new JT808PushData(0x8201, msgBodyBytes, data);
    }
    //查询指定终端参数
    public static JT808PushData querySpecifiedParameters_0x8106(QuerySpecifiedParameters data)
    {
        byte[] msgBodyBytes = BitOperator.integerTo1Bytes(data.getIds().size());
        for (Integer id : data.getIds())
        {
            msgBodyBytes = BitOperator.concatAll(msgBodyBytes, BitOperator.integerTo1Bytes(id));
        }
        return new JT808PushData(0x8106, msgBodyBytes, data);
    }
    //查询终端属性
    public static JT808PushData queryTerminalProperties_0x8107(DistributeEntity data)
    {
        byte[] msgBodyBytes = new byte[0];
        return new JT808PushData(0x8107, msgBodyBytes, data);
    }
    //提问下发
    public static JT808PushData quizSend_0x8302(Quiz data)
    {
        String[] hexFlag = new String[8];
        hexFlag[0] = data.isUrgency() ? "1" : "0";
        hexFlag[3] = data.isTtsPlay() ? "1" : "0";
        hexFlag[4] = data.isScreenDisplay() ? "1" : "0";
        int flag = Integer.parseInt("000" + hexFlag[4] + hexFlag[3] + "00" + hexFlag[0], 2);
        byte[] msgBodyBytes = BitOperator.concatAll(BitOperator.integerTo1Bytes(flag),
                BitOperator.integerTo1Bytes(data.getQuestion().length()),
                BitOperator.stringToBytes(data.getQuestion()));
        for (Answer item : data.getAnswers())
        {
            msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                    BitOperator.integerTo1Bytes(item.getId()),
                    BitOperator.integerTo2Bytes(item.getContent().length()),
                    BitOperator.stringToBytes(item.getContent())
            );
        }
        return new JT808PushData(0x8302, msgBodyBytes, data);
    }
    //设置圆形区域
    public  JT808PushData setCircleArea_0x8600(SetCircleArea data)
    {
        byte[] msgBodyBytes = BitOperator.concatAll(BitOperator.integerTo1Bytes(data.getFlag()),
                BitOperator.integerTo1Bytes(data.getItems().size()));
        for (CircleAreaInfo item :
                data.getItems())
        {
            int areaFlag = getAreaProp_Circle(item.getAreaProperty());
            msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                    BitOperator.integerTo4Bytes(item.getAreaId()),
                    BitOperator.integerTo2Bytes(areaFlag),
                    BitOperator.integerTo4Bytes((int) (item.getCenterLat() * 1000000)),
                    BitOperator.integerTo4Bytes((int) (item.getCenterLng() * 1000000)),
                    BitOperator.integerTo4Bytes(item.getRadius()));
            if (item.getAreaProperty().isbTime())
            {
                msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                        BCD8421Operater.DateToBCD6(item.getBeginTime()),
                        BCD8421Operater.DateToBCD6(item.getEndTime()));
            }
            if (item.getAreaProperty().isbSpeed())
            {
                msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                        BitOperator.integerTo2Bytes(item.getMaxSpeed()),
                        BitOperator.integerTo1Bytes(item.getOverSpeedTime()));
            }
        }
        return new JT808PushData(0x8600, msgBodyBytes, data);
    }

    private static int getAreaProp_Circle(AreaProperty item)
    {
        String[] hexFlag = new String[16];
        hexFlag[0] = item.isbTime() ? "1" : "0";
        hexFlag[1] = item.isbSpeed() ? "1" : "0";
        hexFlag[2] = item.isbInToDriver() ? "1" : "0";
        hexFlag[3] = item.isbInToPlat() ? "1" : "0";
        hexFlag[4] = item.isbOutToDriver() ? "1" : "0";
        hexFlag[5] = item.isbOutToPlat() ? "1" : "0";
        hexFlag[6] = String.valueOf(item.getLatType());
        hexFlag[7] = String.valueOf(item.getLongType());
        hexFlag[8] = String.valueOf(item.getAllowOpenDoor());
        hexFlag[9] = "0";
        hexFlag[10] = "0";
        hexFlag[11] = "0";
        hexFlag[12] = "0";
        hexFlag[13] = "0";
        hexFlag[14] = String.valueOf(item.getOpenCommunicationModule());
        hexFlag[15] = String.valueOf(item.getCollectGNSSInfo());
        String str = "";
        for (int n = hexFlag.length - 1; n <= 0; n--)
        {
            str += hexFlag[n];
        }
        int areaFlag = Integer.parseInt(str, 2);
        return areaFlag;
    }
    //设置终端参数
    public static JT808PushData setParameters_0x8103(SetParameters data)
    {
        byte[] msgBodyBytes = BitOperator.integerTo1Bytes(data.getItems().size());
        for (ParamItem item : data.getItems())
        {
            msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                    BitOperator.integerTo4Bytes(item.getId()));
            switch(item.getId())
            {
                case 0x0013:{
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(BitOperator.stringToBytes(item.getValue()).length),
                            BitOperator.stringToBytes(item.getValue()));
                    break;
                }
                case 0x0018:{
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(4),
                            BitOperator.integerTo4Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x0050:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(4),
                            BitOperator.integerTo4Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x0055:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(4),
                            BitOperator.integerTo4Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x0056:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(4),
                            BitOperator.integerTo4Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x0057:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(4),
                            BitOperator.integerTo4Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x0058:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(4),
                            BitOperator.integerTo4Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x0059:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(4),
                            BitOperator.integerTo4Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x005A:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(4),
                            BitOperator.integerTo4Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x005B:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(2),
                            BitOperator.integerTo2Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x005C:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(2),
                            BitOperator.integerTo2Bytes(Integer.parseInt(item.getValue())));
                    break;
                }

                case 0x0064:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(4),
                            BitOperator.integerTo4Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x0020:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(4),
                            BitOperator.integerTo4Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x0021:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(4),
                            BitOperator.integerTo4Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x0027:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(4),
                            BitOperator.integerTo4Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x0028:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(4),
                            BitOperator.integerTo4Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x0029:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(4),
                            BitOperator.integerTo4Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x002C:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(4),
                            BitOperator.integerTo4Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x002D:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(4),
                            BitOperator.integerTo4Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x002E:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(4),
                            BitOperator.integerTo4Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x002F:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(4),
                            BitOperator.integerTo4Bytes(Integer.parseInt(item.getValue())));
                    break;
                }

                case 0xF500:
                {
                    String value = item.getValue();
                    //如果是高精度后续字段数据才有效
                    if (value.substring(0, 1).equals("3")){
                        byte[] highPrecision = BitOperator.stringToBytes(item.getValue());
                        msgBodyBytes = BitOperator.concatAll(msgBodyBytes,BitOperator.integerTo1Bytes(highPrecision.length),highPrecision);
                    }else{
                        //如果是其他定位模式，后续数据字段为空
                        byte[] highPrecision = BitOperator.stringToBytes(item.getValue().substring(0,1));
                        msgBodyBytes = BitOperator.concatAll(msgBodyBytes,BitOperator.integerTo1Bytes(highPrecision.length),highPrecision);
                    }
                    break;
                }
                //设置阈值
                //1.满载参数 id:0x001A 长度：2 取值范围：0-0xFFFF 默认0
                case 0x001A:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(2),
                            BitOperator.integerTo2Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                //2.超载条件参数 id:0x001B 长度：2 取值范围：0-0xFFFF 默认0
                case 0x001B:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(2),
                            BitOperator.integerTo2Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                //3.严重超载条件参数 id:0x001D 长度：2 取值范围：0-0xFFFF 默认0
                case 0x001D:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(2),
                            BitOperator.integerTo2Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                //下发设置顶灯 id:0x00A0 长度：2 第一字节表示亮灯策略，第二个字节代表亮灯时间
                //第一个字节低三位分别表示绿，黄，红，0关1开 第四位表示是否频闪 0常亮 大于等于1表示频闪频率(单位秒)
                case 0x00A0:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(2),
                            BitOperator.integerTo2Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                //下发语音播报开关指令
                case 0x00A1:
                { msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                        BitOperator.integerTo1Bytes(1),
                        BitOperator.integerTo1Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                //下发密闭检测指令
                case 0x00A2:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(1),
                            BitOperator.integerTo1Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                case 0x0075:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(BitOperator.stringToBytes(item.getValue()).length),
                            BitOperator.stringToBytes(item.getValue()));
                    break;
                }
                case 0x0083:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(BitOperator.stringToBytes(item.getValue()).length),
                            BitOperator.stringToBytes(item.getValue()));
                    break;
                }
                case 0x00FC:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(BitOperator.stringToBytes(item.getValue()).length),
                            BitOperator.stringToBytes(item.getValue()));
                    break;
                }
                case 0x00FD:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(BitOperator.stringToBytes(item.getValue()).length),
                            BitOperator.stringToBytes(item.getValue()));
                    break;
                }
                case 0x00FE:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(BitOperator.stringToBytes(item.getValue()).length),
                            BitOperator.stringToBytes(item.getValue()));
                    break;
                }
                case 0x00FF:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(BitOperator.stringToBytes(item.getValue()).length),
                            BitOperator.stringToBytes(item.getValue()));
                    break;
                }
                case 0x001E:
                {
                    msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                            BitOperator.integerTo1Bytes(1),
                            BitOperator.integerTo1Bytes(Integer.parseInt(item.getValue())));
                    break;
                }
                default:msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                        BitOperator.integerTo1Bytes(BitOperator.stringToBytes(item.getValue()).length),
                        BitOperator.stringToBytes(item.getValue()));
                    break;
            }
        }

        return new JT808PushData(0x8103, msgBodyBytes,  data);
    }

    //设置多边形区域
    public  JT808PushData setPolygonArea_0x8604(SetPolygonArea data)
    {
        int areaFlag = getAreaProp_SetPolygon(data.getAreaProperty());
        byte[] msgBodyBytes = BitOperator.concatAll(
                BitOperator.integerTo4Bytes(data.getAreaId()),
                BitOperator.integerTo2Bytes(areaFlag));
        if (data.getAreaProperty().isbTime())
        {
            msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                    BCD8421Operater.DateToBCD6(data.getBeginTime()),
                    BCD8421Operater.DateToBCD6(data.getEndTime()));
        }
        if (data.getAreaProperty().isbSpeed())
        {
            msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                    BitOperator.integerTo2Bytes(data.getMaxSpeed()),
                    BitOperator.integerTo1Bytes(data.getOverSpeedTime()));
        }
        msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                BitOperator.integerTo2Bytes(data.getLatLngs().size()));
        for (LatLng item : data.getLatLngs())
        {
            msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                    BitOperator.integerTo4Bytes((int) (item.getLat() * 1000000)),
                    BitOperator.integerTo4Bytes((int) (item.getLng() * 1000000)));
        }
        return new JT808PushData(0x8604, msgBodyBytes, data);
    }

    private static int getAreaProp_SetPolygon(AreaProperty item)
    {
        String[] hexFlag = new String[16];
        hexFlag[0] = item.isbTime() ? "1" : "0";
        hexFlag[1] = item.isbSpeed() ? "1" : "0";
        hexFlag[2] = item.isbInToDriver() ? "1" : "0";
        hexFlag[3] = item.isbInToPlat() ? "1" : "0";
        hexFlag[4] = item.isbOutToDriver() ? "1" : "0";
        hexFlag[5] = item.isbOutToPlat() ? "1" : "0";
        hexFlag[6] = String.valueOf(item.getLatType());
        hexFlag[7] = String.valueOf(item.getLongType());
        hexFlag[8] = String.valueOf(item.getAllowOpenDoor());
        hexFlag[9] = "0";
        hexFlag[10] = "0";
        hexFlag[11] = "0";
        hexFlag[12] = "0";
        hexFlag[13] = "0";
        hexFlag[14] = String.valueOf(item.getOpenCommunicationModule());
        hexFlag[15] = String.valueOf(item.getCollectGNSSInfo());
        String str = "";
        for (int n = hexFlag.length - 1; n <= 0; n--)
        {
            str += hexFlag[n];
        }
        int areaFlag = Integer.parseInt(str, 2);
        return areaFlag;
    }

    //设置矩形区域
    public  JT808PushData setRectanglArea_0x8602(SetRectanglArea data)
    {
        byte[] msgBodyBytes = BitOperator.concatAll(BitOperator.integerTo1Bytes(data.getFlag()),
                BitOperator.integerTo1Bytes(data.getItems().size()));
        for (RectanglAreaInfo item :
                data.getItems())
        {
            int areaFlag = getAreaProp_SetRectangl(item.getAreaProperty());
            msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                    BitOperator.integerTo4Bytes(item.getAreaId()),
                    BitOperator.integerTo2Bytes(areaFlag),
                    BitOperator.integerTo4Bytes((int) (item.getLeftTopLat() * 1000000)),
                    BitOperator.integerTo4Bytes((int) (item.getLeftTopLng() * 1000000)),
                    BitOperator.integerTo4Bytes((int) (item.getRightBelowLat() * 1000000)),
                    BitOperator.integerTo4Bytes((int) (item.getRightBelowLng() * 1000000)));
            if (item.getAreaProperty().isbTime())
            {
                msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                        BCD8421Operater.DateToBCD6(item.getBeginTime()),
                        BCD8421Operater.DateToBCD6(item.getEndTime()));
            }
            if (item.getAreaProperty().isbSpeed())
            {
                msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                        BitOperator.integerTo2Bytes(item.getMaxSpeed()),
                        BitOperator.integerTo1Bytes(item.getOverSpeedTime()));
            }
        }
        return new JT808PushData(0x8602, msgBodyBytes, data);
    }

    private static int getAreaProp_SetRectangl(AreaProperty item)
    {
        String[] hexFlag = new String[16];
        hexFlag[0] = item.isbTime() ? "1" : "0";
        hexFlag[1] = item.isbSpeed() ? "1" : "0";
        hexFlag[2] = item.isbInToDriver() ? "1" : "0";
        hexFlag[3] = item.isbInToPlat() ? "1" : "0";
        hexFlag[4] = item.isbOutToDriver() ? "1" : "0";
        hexFlag[5] = item.isbOutToPlat() ? "1" : "0";
        hexFlag[6] = String.valueOf(item.getLatType());
        hexFlag[7] = String.valueOf(item.getLongType());
        hexFlag[8] = String.valueOf(item.getAllowOpenDoor());
        hexFlag[9] = "0";
        hexFlag[10] = "0";
        hexFlag[11] = "0";
        hexFlag[12] = "0";
        hexFlag[13] = "0";
        hexFlag[14] = String.valueOf(item.getOpenCommunicationModule());
        hexFlag[15] = String.valueOf(item.getCollectGNSSInfo());
        String str = "";
        for (int n = hexFlag.length - 1; n <= 0; n--)
        {
            str += hexFlag[n];
        }
        int areaFlag = Integer.parseInt(str, 2);
        return areaFlag;
    }
    //设置路线
    public JT808PushData setRoute_0x8606(SetRoute data)
    {
        int routeProp = getRouteProp(data.getRouteProperty());
        byte[] msgBodyBytes = BitOperator.concatAll(
                BitOperator.integerTo4Bytes(data.getRouteId()),
                BitOperator.integerTo2Bytes(routeProp));
        if (data.getRouteProperty().isbTime())
        {
            msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                    BCD8421Operater.DateToBCD6(data.getBeginTime()),
                    BCD8421Operater.DateToBCD6(data.getEndTime()));
        }
        msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                BitOperator.integerTo2Bytes(data.getInflexions().size()));
        for (InflexionInfo item :
                data.getInflexions())
        {
            int lingProp = getLineProp(item.getLineProperty());
            msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                    BitOperator.integerTo4Bytes(item.getInflexionId()),
                    BitOperator.integerTo4Bytes(item.getLineId()),
                    BitOperator.integerTo4Bytes((int) (item.getLat() * 1000000)),
                    BitOperator.integerTo4Bytes((int) (item.getLng() * 1000000)),
                    BitOperator.integerTo1Bytes(item.getLineWith()),
                    BitOperator.integerTo1Bytes(lingProp));
            if (item.getLineProperty().isbTime())
            {
                msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                        BitOperator.integerTo2Bytes(item.getLineDriverOutTime()),
                        BitOperator.integerTo2Bytes(item.getLineDriverShortTime()));
            }
            if (item.getLineProperty().isbSpeed())
            {
                msgBodyBytes = BitOperator.concatAll(msgBodyBytes,
                        BitOperator.integerTo2Bytes(item.getLineMaxSpeed()),
                        BitOperator.integerTo1Bytes(item.getLineOverSpeedTime()));
            }
        }
        return new JT808PushData(0x8606, msgBodyBytes, data);
    }

    private static int getRouteProp(RouteProperty item)
    {
        String[] hexFlag = new String[8];
        hexFlag[0] = item.isbTime() ? "1" : "0";
        hexFlag[1] = "0";
        hexFlag[2] = item.isbInToDriver() ? "1" : "0";
        hexFlag[3] = item.isbInToPlat() ? "1" : "0";
        hexFlag[4] = item.isbOutToDriver() ? "1" : "0";
        hexFlag[5] = item.isbOutToPlat() ? "1" : "0";
        hexFlag[6] = "0";
        hexFlag[7] = "0";
        String str = "";
        for (int n = hexFlag.length - 1; n <= 0; n--)
        {
            str += hexFlag[n];
        }
        int areaFlag = Integer.parseInt(str, 2);
        return areaFlag;
    }

    private static int getLineProp(LineProperty item)
    {
        String[] hexFlag = new String[8];
        hexFlag[0] = item.isbTime() ? "1" : "0";
        hexFlag[1] = item.isbSpeed() ? "1" : "0";
        hexFlag[2] = String.valueOf(item.getLatType());
        hexFlag[3] = String.valueOf(item.getLongType());
        hexFlag[4] = "0";
        hexFlag[5] = "0";
        hexFlag[6] = "0";
        hexFlag[7] = "0";
        String str = "";
        for (int n = hexFlag.length - 1; n <= 0; n--)
        {
            str += hexFlag[n];
        }
        int areaFlag = Integer.parseInt(str, 2);
        return areaFlag;
    }
    //摄像头立即拍摄命令
    public static JT808PushData takePhotoRightAway_0x8801(TakePhotoRightAway data)
    {
        byte[] msgBodyBytes = BitOperator.concatAll(
                BitOperator.integerTo1Bytes(data.getChannelId()),
                BitOperator.integerTo2Bytes(data.getCmd()),
                BitOperator.integerTo2Bytes(data.getTime()),
                BitOperator.integerTo1Bytes(data.getSaveType()),
                BitOperator.integerTo1Bytes(data.getResolutionRatio()),
                BitOperator.integerTo1Bytes(data.getQuality()),
                BitOperator.integerTo1Bytes(data.getBrightness()),
                BitOperator.integerTo1Bytes(data.getContrast()),
                BitOperator.integerTo1Bytes(data.getSaturation()),
                BitOperator.integerTo1Bytes(data.getChroma())
        );
        return new JT808PushData(0x8801, msgBodyBytes , data);
    }
    //终端控制
    public static JT808PushData terminalControl_0x8105(TerminalControl data)
    {
        byte[] msgBodyBytes = BitOperator.concatAll(BitOperator.integerTo1Bytes(data.getCmd()),
                BitOperator.stringToBytes(data.getValue()));
        return new JT808PushData(0x8105, msgBodyBytes, data);
    }
    //文本信息下发
    //文本信息下发
    public  JT808PushData text_0x8300(Text data)
    {
//        String[] hexFlag = new String[8];
//        hexFlag[0] = data.isUrgency() ? "1" : "0";
//        hexFlag[2] = data.isTerminalDisplay() ? "1" : "0";
//        hexFlag[3] = data.isTtsPlay() ? "1" : "0";
//        hexFlag[4] = data.isScreenDisplay() ? "1" : "0";
//        hexFlag[5] = String.valueOf(data.getMsgType());
//        int flag = Integer.parseInt("00" + hexFlag[5] + hexFlag[4] + hexFlag[3] + hexFlag[2] + "0" + hexFlag[0], 2);
        byte[] msgBodyBytes = BitOperator.concatAll(BitOperator.integerTo1Bytes(data.getFlag()), BitOperator.stringToBytes(data.getContent()));
        return new JT808PushData(0x8300, msgBodyBytes, data);
    }

    public  JT808PushData text_send(TextSend data)
    {
        String[] hexFlag = new String[8];
        hexFlag[0] = data.isUrgency() ? "1" : "0";
        hexFlag[2] = data.isTerminalDisplay() ? "1" : "0";
        hexFlag[3] = data.isTtsPlay() ? "1" : "0";
        hexFlag[4] = data.isScreenDisplay() ? "1" : "0";
        hexFlag[5] = String.valueOf(data.getMsgType());
        int flag = Integer.parseInt("00" + hexFlag[5] + hexFlag[4] + hexFlag[3] + hexFlag[2] + "0" + hexFlag[0], 2);
        byte[] msgBodyBytes = BitOperator.concatAll(BitOperator.integerTo1Bytes(flag), BitOperator.stringToBytes(data.getContent()));
        return new JT808PushData(0x8300, msgBodyBytes, data);
    }
    //临时位置跟踪控制
    public static JT808PushData tracePositionInfo_0x8202(TracePositionInfo data)
    {
        byte[] msgBodyBytes = BitOperator.integerTo2Bytes(data.getTimeInterval());
        if (data.getTimeInterval() != 0)
        {
            msgBodyBytes = BitOperator.concatAll(msgBodyBytes, BitOperator.integerTo4Bytes(data.getTimeContinue()));
        }
        return new JT808PushData(0x8202, msgBodyBytes, data);
    }

    public static JT808PushData upgradeData_0x8108(UpgradeData data)
    {
        byte[] msgBodyBytes = BitOperator.concatAll(BitOperator.integerTo1Bytes(data.getType()),
                BitOperator.stringToBytes(data.getManufacturerCode()),
                BitOperator.integerTo1Bytes(data.getVersion().length()),
                BitOperator.stringToBytes(data.getVersion()),
                BitOperator.integerTo4Bytes(data.getData().length() / 2),
                HexStrUtil.decodeHex(data.getData())
        );
        return new JT808PushData(0x8108, msgBodyBytes, data);
    }

    public JT808PushData IllegalCarCheck_0x8624(IllegalCarCheck data){
        byte[] msgBodyBytes = BitOperator.concatAll(BitOperator.integerTo4Bytes((int) (data.getCenterLng() *1000000)),
                BitOperator.integerTo4Bytes((int)(data.getCenterLat() * 1000000)),
                BitOperator.integerTo1Bytes(data.getDistance()),
                BCD8421Operater.DateToBCD6(data.getStartTime()),
                BCD8421Operater.DateToBCD6(data.getEndTime()));
        return new JT808PushData(0x8624,msgBodyBytes,data);
    }

    /**
     * 农机设备自动标定
     */
    public static JT808PushData AutoCalibration(DistributeEntity data)
    {
        byte[] msgBodyBytes = new byte[0];
        return new JT808PushData(0x8903, msgBodyBytes, data);
    }



}
